#include "syntax_parser.h"
#include "errors_warnings.h"

#include "main_container.h"
extern MainContainer * CompilerData;

// <method_labels> ~ <label> <method_labels>  {NAME}
// <method_labels> ~ ? {NAME, if, while, for, do, switch, break, continue, return, goto,
//						start, stop, derivation, trace, int, float, bool, state,
//						time, void, Facility, Storage, Queue, ADTable, Group, OutputStream, }}
void Parser::Parse_MethodLabels(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_MethodLabels");
#endif
	LexicUnit currentUnit;
	LexicUnit nextUnit;

	do
	{
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif	
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		nextUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition + 1);
		if((currentUnit.type == LUTypeIdentifier)
			&&(nextUnit.type == LUTypeSpecialCharacter && nextUnit.subtype == SpecialCharacterColon))
		{
			// write type of production in this node
			parent->Production = Gr_MethodLabels__Label_MethodLabels;

			// process nonterminal symbol <label> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_Label(newNode0);
		}

		else if(
			(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordIf) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordWhile) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFor) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordDo) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSwitch) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordBreak) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordContinue) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGoto) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStart) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStop) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordDerivation) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordInt) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFloat) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordBool) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordState) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordTime) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordVoid) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordFacility) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStorage) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordQueue) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordADTable) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGroup) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordOutputStream) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordReturn) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordTrace) ||
			(currentUnit.type == LUTypeIdentifier)
			)
		{
			// write type of production in this node
			parent->Production = Gr_MethodLabels__Label_MethodLabels;
			break;
		}
		else
		{
			// ERROR has been found
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_LABEL_BEGINING);
			// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;
		}
	}while(1);

#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_MethodLabels");
#endif
}

// <label> ~ NAME :  {NAME}
void Parser::Parse_Label(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_Label");
#endif
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif	
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
	if(currentUnit.type == LUTypeIdentifier)	
	{
		// write type of production in this node
		parent->Production = Gr_Label__NAME_spColon;

		// process terminal symbol 'NAME' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterColon)
		{
			// process terminal symbol ':' 
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_COLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}
		
	}
	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_NAME_MATCH);
		// MAKE LOGICAL RECOVERING
	}

#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_Label");
#endif
}


// <return_statement> ~ return <expression> ;  {return}
// <return_statement> ~ return ;  {return}
void Parser::Parse_ReturnStatement(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_ReturnStatement");
#endif

	LexicUnit currentUnit;

#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordReturn)
	{
		// process terminal symbol 'return' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon)
		{

			// write type of production in this node
			parent->Production = Gr_ReturnStatement__return_spSemiCol;

			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
			
		}
		else
		{
			// write type of production in this node
			parent->Production = Gr_ReturnStatement__return_Expression_spSemiCol;

			// process nonterminal symbol <expression> 
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			Parse_Expression(newNode1);

			// process terminal symbol ';' 
			currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
			if(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon)
			{
				SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
				parent->Nodes->Add(newNode2);
				newNode2->LexUnitID=this->CurrentLexicPosition;
				newNode2->Production=Gr_Terminal;
				//increase counter
				CurrentLexicPosition++;
			}
			else
			{
				//report syntactic error
				CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
				//increase counter
				CurrentLexicPosition++;
			}
		}
	}
	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_RETURN_STATEMENT_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_ReturnStatement");
#endif
}


// <start_statement> ~ start <name> ( <arguments> ) with <start_assignments> ;  {start}
// <start_statement> ~ start <name> ( <srguments> ) ;  {start}
void Parser::Parse_StartStatement(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_StartStatement");
#endif

	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordStart)
	{
		// process terminal symbol 'start' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <name> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Name(newNode1);

		// process terminal symbol '(' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterLeftParenthesis)
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_LEFT_PARENTHESIS_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

		// process nonterminal symbol <arguments> 
		SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode3);
		Parse_Arguments(newNode3);

		// process terminal symbol ')' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightParenthesis)
		{
			SyntaxTreeNode * newNode4 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode4);
			newNode4->LexUnitID=this->CurrentLexicPosition;
			newNode4->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_RIGHT_PARENTHESIS_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordWith)
		{
			// write type of production in this node
			parent->Production = Gr_StartStatement__start_Name_spLPar_Arguments_spRPar_with_StartAssignments_spSemiCol;
	
			SyntaxTreeNode * newNode5 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode5);
			newNode5->LexUnitID=this->CurrentLexicPosition;
			newNode5->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

			// process nonterminal symbol <start_assignments> 
			SyntaxTreeNode * newNode6 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode6);
			Parse_StartAssignments(newNode6);

			// process terminal symbol ';' 
			currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
			if(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon)
			{
				SyntaxTreeNode * newNode7 = new SyntaxTreeNode();
				parent->Nodes->Add(newNode7);
				newNode7->LexUnitID=this->CurrentLexicPosition;
				newNode7->Production=Gr_Terminal;
				//increase counter
				CurrentLexicPosition++;
			}
			else
			{
				//report syntactic error
				CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
				//increase counter
				CurrentLexicPosition++;
			}
		}
		else if(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon)
		{
			// write type of production in this node
			parent->Production = Gr_StartStatement__start_Name_spLPar_Arguments_spRPar_spSemiCol;
			
			SyntaxTreeNode * newNode5 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode5);
			newNode5->LexUnitID=this->CurrentLexicPosition;
			newNode5->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error									
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_START_STATEMENT_BEGINING);
			//increase counter
			CurrentLexicPosition++;
		}

	}

	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_START_STATEMENT_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_StartStatement");
#endif
}


// <inf_begin> ~ - INF ;  {-}
// <inf_begin> ~ ? {LITERAL, +, -, ;, }}
void Parser::Parse_InfBegin(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_InfBegin");
#endif
	LexicUnit currentUnit;
	LexicUnit nextUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
	nextUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition + 1);

	if((currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorSubtraction) &&
		(nextUnit.type == LUTypeKeyword && nextUnit.subtype == KeywordINF)
		)
	{
		
		// write type of production in this node
		parent->Production = Gr_InfBegin__opSub_INF_spSemiCol;

		// process terminal symbol '-' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process terminal symbol 'INF' 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		newNode1->LexUnitID=this->CurrentLexicPosition;
		newNode1->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon)
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}
	}
	else if((currentUnit.type == LUTypeConstantBool || currentUnit.type == LUTypeConstantFloat || currentUnit.type == LUTypeConstantInteger) ||
		(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorAddition) ||
		(currentUnit.type == LUTypeOperator && currentUnit.subtype == OperatorSubtraction) ||
		(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon) ||
		(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace)
		)
	{
		parent->Production = Gr_InfBegin__epsilon;
		// this is epsilon part of production
		// new node is not needed
		// there are no symbols on the right side of this production
		// so that all
	}
	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_INF_BEGIN_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_InfBegin");
#endif
}


// <block_labels> ~ ? {generate, terminate, advance, enter, leave, seize, release, inqueue, outqueue, arrive, depart, model, goto, if, wait, join, create, split, gather, execute, exec, NAME}
// <block_labels> ~ <block_label> <block_labels>  {NAME}
void Parser::Parse_BlockLabels(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_BlockLabels");
#endif
	LexicUnit currentUnit;
	LexicUnit firstUnit;
	LexicUnit secondUnit;
	LexicUnit thirdUnit;

	do
	{
		firstUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition + 1);
		secondUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition + 2);
		thirdUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition + 3);
		#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Getting lexic unit.");
		#endif
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		
		if(currentUnit.type == LUTypeIdentifier)
		{
			
			if((firstUnit.type == LUTypeSpecialCharacter && firstUnit.subtype == SpecialCharacterColon) ||
				((firstUnit.type == LUTypeSpecialCharacter && firstUnit.subtype == SpecialCharacterPeriod) &&
				(secondUnit.type == LUTypeIdentifier) &&
				(thirdUnit.type == LUTypeSpecialCharacter && thirdUnit.subtype == SpecialCharacterColon))
				)
			{
				// write type of production in this node
				parent->Production = Gr_BlockLabels__BlockLabel_BlockLabels;

				// process nonterminal symbol <block_label> 
				SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
				parent->Nodes->Add(newNode0);
				Parse_BlockLabel(newNode0);

			}
			else
			{
				parent->Production = Gr_BlockLabels__BlockLabel_BlockLabels;
				// this is epsilon part of production
				// new node is not needed
				// there are no symbols on the right side of this production
				// so that all
				break;
			}
		}
		else if((currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGenerate) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordTerminate) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordAdvance) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordEnter) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordLeave) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSeize) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordRelease) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordInqueue) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordOutqueue) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordArrive) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordDepart) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordModel) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGoto) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordIf) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordWait) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordJoin) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordCreate) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSplit) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGather) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordExecute) ||
			(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordExec))	
		{
			parent->Production = Gr_BlockLabels__BlockLabel_BlockLabels;
			// this is epsilon part of production
			// new node is not needed
			// there are no symbols on the right side of this production
			// so that all
			break;
		}
		else
		{
			// ERROR has been found
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_BLOCK_LABELS_BEGINING);
			// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;
		}
	}
	while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_BlockLabels");
#endif
}


// <block_label> ~ NAME :  {NAME}
// <block_label> ~ NAME . NAME :  {NAME}
void Parser::Parse_BlockLabel(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_BlockLabel");
#endif

	LexicUnit currentUnit;

#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if(currentUnit.type == LUTypeIdentifier)
	{
		// process terminal symbol 'NAME' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterColon)
		{
			// write type of production in this node
			parent->Production = Gr_BlockLabel__NAME_spColon;

			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

		}
		else if(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterPeriod)
		{
			// write type of production in this node
			parent->Production = Gr_BlockLabel__NAME_spPer_NAME_spColon;

			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;

			// process terminal symbol 'NAME' 
			currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
			if(currentUnit.type == LUTypeIdentifier)
			{
				SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
				parent->Nodes->Add(newNode2);
				newNode2->LexUnitID=this->CurrentLexicPosition;
				newNode2->Production=Gr_Terminal;
				//increase counter
				CurrentLexicPosition++;
			}
			else
			{
				//report syntactic error 
				CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_NAME_MATCH);
				//increase counter
				CurrentLexicPosition++;
			}

			// process terminal symbol ':' 
			currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
			if(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterColon)
			{
				SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
				parent->Nodes->Add(newNode3);
				newNode3->LexUnitID=this->CurrentLexicPosition;
				newNode3->Production=Gr_Terminal;
				//increase counter
				CurrentLexicPosition++;
			}
			else
			{
				//report syntactic error  
				CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_COLON_MATCH);
				//increase counter
				CurrentLexicPosition++;
			}
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_PERIOD_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}
	}
	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_BLOCK_LABEL_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_BlockLabel");
#endif
}



// <value_pairs_adds> ~ ? {;, }}
// <value_pairs_adds> ~ <value_pair_add> <value_pairs_adds>  {;}
void Parser::Parse_ValuePairsAdds(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_ValuePairsAdds");
#endif
	LexicUnit currentUnit;
	LexicUnit firstUnit;
	LexicUnit secondUnit;
	
	do
	{
		#ifdef TRACE
			CompilerData->LogTrace->ReportLine("Getting lexic unit.");
		#endif
		// get current lexic unit
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		firstUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition + 1);
		secondUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition + 2);

		if((currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon))
		{	
			if((firstUnit.type == LUTypeOperator && firstUnit.subtype == OperatorAddition) && 
			(secondUnit.type == LUTypeKeyword && secondUnit.subtype == KeywordINF))
			{
				// epsilon production
				parent->Production = Gr_ValuePairs__ValuePair_ValuePairsAdds;
				break;
			}
			else
			{
				// write type of production in this node
				parent->Production = Gr_ValuePairs__ValuePair_ValuePairsAdds;

				// process nonterminal symbol <value_pair_add> 
				SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
				parent->Nodes->Add(newNode0);
				Parse_ValuePairAdd(newNode0);
			}
		}
		else if((currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightCurlyBrace))
		{
			// this is epsilon part of production
			// new node is not needed
			// there are no symbols on the right side of this production
			// so that all
			parent->Production = Gr_ValuePairs__ValuePair_ValuePairsAdds;
			break;
		}
		else
		{
			// ERROR has been found
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_VALUE_PAIRS_ADDS_BEGINING);
			// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;
		}
	}
	while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_ValuePairsAdds");
#endif
}
	


/*
void Parser::Parse_StartAssignments(SyntaxTreeNode * parent)
{
}*/
/*
void Parser::Parse_SimpleStatement(SyntaxTreeNode * parent)
{
}
*/
/*
void Parser::Parse_VariableValue(SyntaxTreeNode * parent)
{
}*/